'''
Created on 2011-11-13

@first author: latios
'''

import os
import re
import sys
import csv
import iws
from PyQt4.QtGui import *
from acquiredialog import AcquireDialog
from PyQt4.QtCore import *
from PyQt4.QtNetwork import *
from ui.mainwindow import Ui_MainWindow
from tagger import COL

import timeLine


def join(lst,sep):
	ret=''
	if (len(lst)==0):return ''
	if (len(lst)==1):return lst[0]
	
	for i in range(len(lst)-1):
		ret += lst[i]+sep
	return ret+lst[len(lst)-1]

def isNTFS(str):
	return str=='NTFS'

def isREG(str):
	return str=='REG'

def isEventlog(str):
	return str != 'NTFS' and str!='REG'

def match(filters,str):
	ret = False
	for f in filters:
		ret = ret or f(str)
	return ret

class MainWindow (QMainWindow, Ui_MainWindow):
	def __init__(self, parent=None):
		QMainWindow.__init__(self, parent)
		#TODO: integrate webview
		# iws.start('timeline/',7788,'index.html')
		self.setupUi(self)
		self.acquiredialog=None
		self._data = []
		self._header=[]
		self._model = []
	def actionFileOpen_triggered(self):
		filename = QFileDialog.getOpenFileName(self, "open csv file")
		if (filename == ''): return
		self.readCSV(filename)
	def filters_changed(self):
		self.applyFilter()
	def closeEvent(self,event):
		print 'stop iws'
		iws.stop()
		QMainWindow.closeEvent(self,event)
	def applyFilter(self):
		filters=[]
		if (self.cbxRegistry.isChecked()):filters.append(isREG)
		if (self.cbxNTFS.isChecked()):filters.append(isNTFS)
		if self.cbxEventlog.isChecked():filters.append(isEventlog)
#		filterRe = re.compile('|',join(filters))
#		if (len(filters)==0):filter = re.compile(".")
		del self._model[0:]
		progress = QProgressDialog('apply filter...','cancel',1,self._model.__len__(),self)
		progress.setAutoClose(True)
		for i in range(1,self._data.__len__()):
			if (match(filters,self._data[i-1][1])):
				self._model.append(self._data[i-1])
			progress.setValue(i)
		progress.hide()
		self.updateTableWidget()
	def actionAcquire_triggered(self):
		if (self.acquiredialog==None):
			self.acquiredialog=AcquireDialog(self)
		if (self.acquiredialog.exec_()==QDialog.Accepted):
			self.readCSV(self.acquiredialog.OutputPath)
	def treeitem_doubleclicked(self,item):
		QMessageBox.warning(self,'',str(item)+' D clicked')
	def updateSummaryView(self):
		#susceptible events
		sus = [r for r in self._data 
			   if r[COL.tamper]!='']
		self.treeTamper.clear()
		if (len(sus)>0):
			self.treeTamper.setColumnCount(3)#len(sus[0]))
		for r in sus:
			self.treeTamper.addTopLevelItem(QTreeWidgetItem(
				[r[COL.time],r[COL.target],r[COL.tamper]]))
			
		#file modification
		files=[r for r in self._data 
			   if r[COL.src]=='NTFS' and r[COL.target][-1]!='\\']
		filesum=dict()
		for r in files:
			filesum.setdefault(r[COL.action],set()).add((r[COL.time],r[COL.target]))
		self.treeFileOp.clear()
		for (action,time_filename) in filesum.items():
			item = QTreeWidgetItem(['%d files' % len(time_filename),action])
			self.treeFileOp.addTopLevelItem(item)
			for (time,filename) in time_filename:
				item.addChild(QTreeWidgetItem([time,filename]))
		#folder modify 
		folders=[r for r in self._data 
			   if r[COL.src]=='NTFS' and r[COL.target][-1]=='\\']
		foldersum=dict()
		for r in folders:
			foldersum.setdefault(r[COL.action],set()).add((r[COL.time],r[COL.target]))
		self.treeFolderOp.clear()
		for (action,time_filename) in foldersum.items():
			item = QTreeWidgetItem(['%d folders' % len(time_filename),action])
			self.treeFolderOp.addTopLevelItem(item)
			for (time,filename) in time_filename:
				item.addChild(QTreeWidgetItem([time,filename]))
		#program executed
		progs = [r for r in self._data if r[COL.src]=='REG::UA']
		self.treeProgram.clear()
		##self.treeProgram.setRowCount(len(progs))
		for (p,idx) in zip(progs,range(len(progs))):
			item = QTreeWidgetItem([p[COL.target],p[COL.time]])
			self.treeProgram.addTopLevelItem(item)
			#'''self.treeProgram.setItem(idx,0,QTableWidgetItem(p[COL.target]))
			#self.treeProgram.setItem(idx,1,QTableWidgetItem(p[COL.time]))'''
		#office files
		'''
		officeEntry = office.apply(self._data)
		self.treeOfficeSession.clear()
		for subTreeKey in officeEntry:
			treeItem = QTreeWidgetItem([subTreeKey])
			self.treeOfficeSession.addTopLevelItem(treeItem)
			list = officeEntry[subTreeKey]
			for subList in list:
				treeItem.addChild(QTreeWidgetItem(subList))
		print officeEntry
		'''
		timeLine.applyData(self.treeOfficeSession, self._data)
			
		 
	def updateTableWidget(self):
		'''
		put self._model into widget display
		'''
		self.tableWidget.clearContents()
		self.tableWidget.setColumnCount(len(self._header))
		self.tableWidget.setRowCount(len(self._model))
		self.tableWidget.setHorizontalHeaderLabels(self._header)
		self.tableWidget.setSortingEnabled(False)
		for i in range(len(self._model)):
			if self._model[i][1]=='REG':
				color = QColor(255,200,200)
			elif self._model[i][1]=='NTFS':
				color=QColor(200,200,255)
			else: color=QColor(255,255,255)
			for j in range(len(self._header)):
				item = QTableWidgetItem(QString(self._model[i][j]))
				item.setBackgroundColor(QColor(color))
				self.tableWidget.setItem(i,j,item)
		self.tableWidget.setSortingEnabled(True)
	def readCSV(self, filename):
		self._data=[]
		with open(filename) as f:
			reader = csv.reader(f)
			firstLine = True
			for row in reader:
				if (firstLine):
					self._header=row
					firstLine=False
				else :
					
					if (row.__len__()<self._header.__len__()):
						#extend each row incase of index-outof-range
						row.extend(['']*(len(self._header)-len(row)))
					urow=[]
					for cell in row:
						try:
							urow.append(unicode(cell,'gb2312'))
						except UnicodeDecodeError,e:
							try:
								urow.append(unicode(cell,'utf8'))
							except UnicodeDecodeError,e:
								urow.append(unicode(cell,'ascii',errors='ignore'))
								#print "cant encode:"+cell
					self._data.append(urow)
		self.applyFilter()
		self.updateTableWidget()
		self.updateSummaryView()
		#TODO:update timeline
		'''import tln2xml
		tln2xml.toXML(self._data,'timeline\\out.xml')
		self.webView.load(QUrl('http://localhost:7788/?out.xml'))
		os.system('start http://localhost:7788')'''
	def reload_clicked(self):
		self.webView.load(QUrl(self.lineUrl.text()))
	def webView_urlChanged(self,url):
		self.lineUrl.setText(url.toString())
		
if (__name__=='__main__'):
	app = QApplication(sys.argv)
	QNetworkProxyFactory.setUseSystemConfiguration(True)
	mainwindow = MainWindow();
	mainwindow.setWindowState(mainwindow.windowState() | Qt.WindowMaximized);
	mainwindow.show()
	app.exec_()
